package com.woniu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.comment.util.StateData;
import com.woniu.exception.RebornException;
import com.woniu.mapper.JunkTypeMapper;
import com.woniu.model.JunkType;
import com.woniu.service.JunkTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.service.param.AddJunkTypeParam;
import com.woniu.service.param.ChangeFatherParam;
import com.woniu.service.param.ChangeStatusParam;
import com.woniu.service.param.PageParam;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2024年05月23日
 */
@Service
public class JunkTypeServiceImpl extends ServiceImpl<JunkTypeMapper, JunkType> implements JunkTypeService {
    @Resource
    private JunkTypeMapper junkTypeMapper;

    /**
     * 添加垃圾类型
     *
     * @param newType 新的垃圾类型参数
     * @throws RuntimeException 如果父类id不存在或已被删除
     */
    @Override
    public void addJunkType(AddJunkTypeParam newType) {
        JunkType fatherType = null;
        if (newType.getFatherId() != 0) {
            //当前传了父id的情况 拿到父类型
            fatherType = junkTypeMapper.selectById(newType.getFatherId());
            //判别父类型id的合法性
            if (fatherType == null) {
                throw new RuntimeException("不存在的父类id");
            }
            if (Objects.equals(fatherType.getState(), 1)) {
                throw new RuntimeException("已被删除的父类id");
            }
        }

        //新增类别
        JunkType junkType = BeanUtil.toBean(newType, JunkType.class);
        junkType.setTypeSelf(StateData.TYPE_IS_SELF);
        //新增的状态分两种
        if (newType.getFatherId() == 0) {
            //当前是一级类别的情况下
            junkType.setState(StateData.TYPE_NORMAL);
        } else {
            //有爹的情况下 把爹的是叶子结点换成不是叶子结点
            assert fatherType != null;//断言爹不为空
            junkType.setState(fatherType.getState());
        }
        //执行新增
        junkTypeMapper.insert(junkType);
        //更新爹的叶子结点
        if (newType.getFatherId() != 0) {
            assert fatherType != null;
            if (Objects.equals(fatherType.getTypeSelf(), StateData.TYPE_IS_SELF)) {
                fatherType.setTypeSelf(StateData.TYPE_NOT_SELF);
                //执行更新
                junkTypeMapper.updateById(fatherType);
            }
        }
    }

    /**
     * 修改垃圾类型
     *
     * @param param 修改父类参数
     * @throws RuntimeException 如果父类型状态错误
     */
    @Override
    public void changeJunkType(ChangeFatherParam param) {
        if (param.getNewParentId() != 0) {
            // 有新爹的情况下，看看新爹是不是叶子结点
            JunkType newFather = junkTypeMapper.selectById(param.getTypeId());
            if (Objects.equals(newFather.getTypeSelf(), StateData.TYPE_IS_SELF)) {
                newFather.setTypeSelf(StateData.TYPE_NOT_SELF);
                junkTypeMapper.updateById(newFather);
            }
        }
        UpdateWrapper<JunkType> updateWrapper = new UpdateWrapper<>();
        JunkType newJunkType = BeanUtil.toBean(param, JunkType.class);
        JunkType father = null;
        if (param.getOldParentId() != 0) {
            father = junkTypeMapper.selectById(param.getOldParentId());
            // 有爹的情况下，先把爹查出来查看状态
            if (Objects.equals(father.getState(), StateData.TYPE_DELETED)) {
                throw new RuntimeException("父类型状态错误");
            }
            // 初始状态为爹的状态
            newJunkType.setState(father.getState());
            // 查询当前爹所有的儿子，如果只有当前类一个儿子，则把当前爹改为叶子结点
            QueryWrapper<JunkType> fatherWrapper = new QueryWrapper<>();
            fatherWrapper.eq("father_id", father.getId());
            List<JunkType> fatherTypes = junkTypeMapper.selectList(fatherWrapper);
            if (fatherTypes.size() == 1) {
                father.setTypeSelf(StateData.TYPE_IS_SELF);
                junkTypeMapper.updateById(father);
            }
        }
        newJunkType.setFatherId(param.getNewParentId());
        // 不用移动儿子，因为儿子跟着自己
        junkTypeMapper.updateById(newJunkType);
    }

    /**
     * 加载所有垃圾类型
     *
     * @param newType 分页参数
     * @return 分页后的垃圾类型
     */
    @Override
    public Page<JunkType> loadAllJunkType(PageParam newType) {
        QueryWrapper<JunkType> queryWrapper = new QueryWrapper<>();
        Integer pageNum = newType.getPageNum();
        Integer pageSize = newType.getPageSize();

        // 判断是否使用默认的分页参数
        if (pageNum <= 0 || pageSize <= 0) {
            // 使用默认的分页参数
            pageNum = 1;
            pageSize = 3;
        }

        // 创建分页对象
        Page<JunkType> page = new Page<>(pageNum, pageSize);

        // 执行分页查询
        Page<JunkType> junkTypePage = junkTypeMapper.selectPage(page, queryWrapper);

        // 返回查询结果
        return junkTypePage;
    }


    /**
     * 修改垃圾类型状态
     *
     * @param param 状态参数
     * @throws RuntimeException 如果状态异常
     */
    @Override
    public void changeStatus(ChangeStatusParam param) {
        if (Objects.equals(param.getTypeState(), StateData.TYPE_DISABLED)) {
            disableType(param.getTypeId());
        } else {
            enableType(param.getTypeId());
        }
    }

    /**
     * 查询垃圾是否是一级类别
     * id:站点id
     */
    @Override
    public JunkType getByIdFather(Integer id) {
        JunkType junkType = junkTypeMapper.selectById(id);
        if (junkType == null) {
            throw new RuntimeException("不存在的垃圾种类id");
        }
        if(!Objects.equals(junkType.getTypeSelf(), StateData.TYPE_IS_SELF)){
            throw new RebornException("仅能选择一级垃圾类别",80001);
        }
        return junkType;
    }

    /**
     * 用户查看垃圾种类
     * list 所有垃圾种类集合
     */
    @Override
    public List<JunkType> checkJunkType() {
        List<JunkType> junkTypes = junkTypeMapper.selectList(new QueryWrapper<JunkType>());
        System.out.println(JSONUtil.parseObj(junkTypes));
        return junkTypes;
    }

    /**
     * 根据垃圾id查询垃圾单位
     * String 单位
     */
    @Override
    public String getUnitById(Integer id) {
        JunkType junkType = junkTypeMapper.selectById(id);
        if (junkType==null){
            throw new RebornException("不存在的垃圾种类",80001);
        }
        return junkType.getTypeUnit();
    }


    /**
     * 根据id集合查找垃圾种类
     * list 垃圾种类id集合
     */
    @Override
    public List<JunkType> getByIdList(List<Integer> ids) {
        QueryWrapper<JunkType> wrapper = new QueryWrapper<>();
        wrapper.in("id",ids);
        return junkTypeMapper.selectList(wrapper);
    }

    /**
     * 启用垃圾类型
     *
     * @param typeId 垃圾类型ID
     * @throws RuntimeException 如果垃圾类型不存在
     */
    private void enableType(Integer typeId) {
        JunkType junkType = junkTypeMapper.selectById(typeId);
        if (junkType == null) {
            throw new RuntimeException("不存在的垃圾种类id");
        }
        //解禁
        //通过递归找到当前类别的所有父类别
        ArrayList<Integer> list = new ArrayList<>();
        list.add(typeId);
        findFather(typeId, list);
        //执行更新
        UpdateWrapper<JunkType> wrapper = new UpdateWrapper<>();
        wrapper.set("state", StateData.TYPE_NORMAL);
        wrapper.in("type_id", list);
        junkTypeMapper.update(null, wrapper);
    }

    /**
     * 递归查找父类
     *
     * @param typeId 类型ID
     * @param list 父类ID列表
     */
    private void findFather(Integer typeId, ArrayList<Integer> list) {
        //通过当前的类别id查询parentId
        JunkType junkType = junkTypeMapper.selectById(typeId);
        //找到没爹为止 一直往上找
        if (junkType.getFatherId() != 0) {
            list.add(junkType.getFatherId());
            findFather(junkType.getFatherId(), list);
        }
    }
    /**
     * 禁用垃圾类型
     *
     * @param typeId 垃圾类型ID
     * @throws RuntimeException 如果垃圾种类不存在或状态异常
     */
    private void disableType(Integer typeId) {
        JunkType junkType = junkTypeMapper.selectById(typeId);
        if (junkType == null) {
            throw new RuntimeException("垃圾种类不存在");
        }
        if (!Objects.equals(junkType.getState(), StateData.TYPE_NORMAL)) {
            throw new RuntimeException("垃圾种类状态异常");
        }
        //禁用
        //通过递归找到当前类别的所有子类别
        ArrayList<Integer> list = new ArrayList<>();
        list.add(typeId);
        findChildren(typeId, list);
        //执行更新
        UpdateWrapper<JunkType> wrapper = new UpdateWrapper<>();
        wrapper.set("state", StateData.TYPE_DISABLED);
        wrapper.in("type_id", list);
        junkTypeMapper.update(null, wrapper);

    }

    /**
     * 递归查找子类
     *
     * @param typeId 类型ID
     * @param list 子类ID列表
     */
    private void findChildren(Integer typeId, ArrayList<Integer> list) {
        QueryWrapper<JunkType> wrapper = new QueryWrapper<>();
        wrapper.eq("father_id", typeId);
        wrapper.ne("state", StateData.TYPE_DELETED);
        //通过typeId查询该类别下的所有子类别
        List<JunkType> children = junkTypeMapper.selectList(wrapper);
        //归条件 当前已没有儿子
        if (children == null || children.size() == 0) {
            return;
        }
        for (JunkType childrenType : children) {
            list.add(childrenType.getTypeId());
            //递归查询
            findChildren(childrenType.getTypeId(), list);
        }
    }

}